package util.apps.gump;

import java.io.*;
import util.gen.*;
import java.util.regex.*;
import java.util.*;

import javax.swing.JTextArea;

public class Gump {
	private File jarFile;
	private JTextArea appName;
	private String[] menu;
	private String appDescription;
	private JTextArea appDescriptionS;
	private Option[] options;
	private String java = "java";
	public static final Pattern startSpace = Pattern.compile("^\\s+");
	public static final Pattern flag = Pattern.compile("^-[a-z]");
	private boolean debug = false;

	public Gump (String[] args){
		//process args
		processArgs(args);
		
		//launch jar application and fetch output
		String[] command = {java, "-jar", jarFile.toString()};
		menu = IO.executeCommandLineReturnAll(command);
		
		Misc.printArray(menu);
		
		//check menu
		checkMenu(command);

		//parse menu
		parseMenu();
		
		//check parsing
		checkMenuParsing();
		
		//print to debug
		if (debug){
			System.out.println("\n"+ appDescription+ "\n");
			Misc.printArray(options);
			System.out.println("\n");
			Misc.printArray(menu);
		}
		
		//make swing bits
		makeSwingComponents();
		
		//make JFrame to collect user data
		GumpDrawFrame df = new GumpDrawFrame(this);
		
		//process user data
		
		//execute
		
		//show execution
		
		
	}
	
	public void makeSwingComponents(){
		appName = new JTextArea(jarFile.getName());
		appName.setEditable(false);
		appName.setFont(GumpApplicationPanel.FONT);
		
		appDescriptionS = new JTextArea(appDescription);
		appDescriptionS.setEditable(false);
		appDescriptionS.setWrapStyleWord(true);
		appDescriptionS.setLineWrap(true);
		appDescriptionS.setFont(GumpApplicationPanel.FONT);
		
		for (int i=0; i< options.length; i++) options[i].makeSwingComponents();
	}
	
	public void checkMenuParsing(){
		if (appDescription == null || options == null || options.length == 0){
			Swing.throwError(null, "Problem parsing comand line menu? No appDescription? No options?\n"+Misc.stringArrayToString(menu, "\n"));
			System.exit(0);
		}
	}
	public void checkMenu(String[] command){
		//executed?
		if (menu == null){
			Swing.throwError(null, "Problem executing java command -> '"+Misc.stringArrayToString(command, " ")+ "'");
			System.exit(0);
		}
		//jar file OK?
		if (menu[0].contains("corrupt")){
			Swing.throwError(null, "Problem executing java jar command. "+menu[0]);
			System.exit(0);
		}
	}


	public void parseMenu(){
		StringBuilder descriptionSB = new StringBuilder();
		
		ArrayList<Option> parametersAL = new ArrayList<Option>();
		boolean pastDescription = false;
		for (int i=0; i< menu.length; i++){
			String line = menu[i].trim();
			//empty?
			if (line.length() == 0) continue;
			//at end?
			if (line.startsWith("Example")) break;
			//skip?
			if (line.startsWith("Option") || line.startsWith("Param") || line.startsWith("*")) continue;
			//parameter?
			Matcher mat = flag.matcher(line);
			if (mat.find()) {
				pastDescription = true;
				while (i < menu.length){
					i++;
					//look at next line, at end?
					if (i == menu.length) {
						parametersAL.add(new Option(line));
						break;
					}
					else {
						//does the next line start with a flag
						String following = menu[i];
						mat = flag.matcher(following);
						if (mat.find()) {
							parametersAL.add(new Option(line));
							i--;
							break;
						}
						
						//does the next line start with white space
						mat = startSpace.matcher(following);
						if (mat.find()){
							//and is not empty
							if (following.trim().length() !=0) line = line +"\n"+following;
							else {
								parametersAL.add(new Option(line));
								break;
							}
						}
						else {
							i--;
							parametersAL.add(new Option(line));
							break;
						}
					}
				}
			}
			//add to appDescription?
			if (pastDescription) continue;
			else {
				descriptionSB.append(line);
				descriptionSB.append(" ");
			}
		}
		//set fields
		appDescription = descriptionSB.toString();
		options = new Option[parametersAL.size()];
		parametersAL.toArray(options);

	}

	public static void main(String[] args) {
		if (args.length ==0){
			printDocs();
			System.exit(0);
		}
		new Gump(args);
	}

	/**This method will process each argument and assign new varibles*/
	public void processArgs(String[] args){
		jarFile = new File(args[0]);
		if (jarFile.canRead() == false) {
			Swing.throwError(null, "Aborting: cannot find java jar application -> "+args[0]);
			System.exit(0);
		}
	}	

	public static void printDocs(){
		System.out.println("\n" +
				"**************************************************************************************\n" +
				"**                                Gump:    Sept 2007                         **\n" +
				"**************************************************************************************\n" +
				"Runs a command line java jar app as a GUI. Enter a package/Apps/xxx.jar file to launch.\n\n"+				

		"**************************************************************************************\n");		
	}
	public File getJarFile() {
		return jarFile;
	}
	public void setJarFile(File jarFile) {
		this.jarFile = jarFile;
	}
	public String[] getMenu() {
		return menu;
	}
	public void setMenu(String[] menu) {
		this.menu = menu;
	}
	public String getDescription() {
		return appDescription;
	}
	public void setDescription(String description) {
		this.appDescription = description;
	}
	public Option[] getOptions() {
		return options;
	}
	public void setOptions(Option[] parameters) {
		this.options = parameters;
	}
	public String getJava() {
		return java;
	}
	public void setJava(String java) {
		this.java = java;
	}

	public JTextArea getAppName() {
		return appName;
	}

	public void setAppName(JTextArea appName) {
		this.appName = appName;
	}

	public String getAppDescription() {
		return appDescription;
	}

	public void setAppDescription(String appDescription) {
		this.appDescription = appDescription;
	}

	public JTextArea getAppDescriptionS() {
		return appDescriptionS;
	}

	public void setAppDescriptionS(JTextArea appDescriptionS) {
		this.appDescriptionS = appDescriptionS;
	}	

}
